package com.aynu.admin.service.base.impl;

import cn.hutool.core.util.StrUtil;
import com.aynu.admin.domain.CommonResponse;
import com.aynu.admin.domain.po.TAccount;
import com.aynu.admin.domain.po.TAuthentication;
import com.aynu.admin.domain.po.TVehicle;
import com.aynu.admin.filter.AuthenticationInterceptor;
import com.aynu.admin.mapper.base.TAccountMapper;
import com.aynu.admin.mapper.base.TAuthenticationMapper;
import com.aynu.admin.service.base.ITAccountService;
import com.aynu.admin.service.base.ITAuthenticationService;
import com.aynu.admin.service.base.ITVehicleService;
import com.aynu.admin.utils.account.AccountIdGenerator;
import com.aynu.admin.utils.redis.RedisDelete;
import com.aynu.admin.utils.redis.RedisQuery;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-02-26
 */
@Service
public class TAccountServiceImpl extends ServiceImpl<TAccountMapper, TAccount> implements ITAccountService {
    @Resource
    private TAccountMapper accountMapper;
    @Resource
    private RedisQuery redisQuery;
    @Resource
    private RedisDelete redisDelete;
    @Resource
    private ITAuthenticationService authenticationService;
    @Resource
    private ITVehicleService vehicleService;
//    @Resource
//    private TAuthenticationMapper authenticationMapper;

    @Override
    public CommonResponse<List<TAccount>> getOnline() {
        Set<String> accountIds = redisQuery.getOnlineAccountIdList("ACCOUNT_TOKEN_");
        if (accountIds.isEmpty()) return CommonResponse.success(Collections.emptyList());
        List<TAccount> tAccounts = accountMapper.selectBatchIds(accountIds);
        return CommonResponse.success(tAccounts);
    }

    @Override
    @Transactional
    public CommonResponse<Object> offline(String accountId) {
        if (redisDelete.deleteInfoAndKey("ACCOUNT_TOKEN_", accountId)) return CommonResponse.SUCCESS;
        return CommonResponse.failed("该用户已下线");
    }

    @Override
    @Transactional
    public CommonResponse<Object> saveAccount(String userPrincipal, TAccount account) {
        TAccount tAccount = accountMapper.selectOne(
                Wrappers
                        .<TAccount>lambdaQuery()
                        .eq(TAccount::getUsername, account.getUsername())
        );
        if (tAccount != null) {
            return CommonResponse.failed("帐号已存在！");
        }
        TAccount tAccount1 = accountMapper.selectOne(
                Wrappers.<TAccount>lambdaQuery()
                        .eq(TAccount::getPhone, account.getPhone())
        );
        if (tAccount1 != null) {
            return CommonResponse.failed("该手机号已被其他用户名绑定");
        }

        AccountIdGenerator idGenerator = new AccountIdGenerator(0, 0);
        account.setCreatedBy(userPrincipal)
                .setUpdatedBy(userPrincipal)
                .setCreatedTime(LocalDateTime.now())
                .setUpdatedTime(LocalDateTime.now())
                .setId(String.valueOf(idGenerator.nextId()))
                .setPassword(DigestUtils.md5DigestAsHex(account.getPassword().getBytes()))
                .setRole(0)
                .setUseralias(account.getUsername())
                .setStatus(0);
        accountMapper.insert(account);

        //insert initial authentication information
        TAuthentication authentication = new TAuthentication(
                String.valueOf(idGenerator.nextId()),
                account.getUsername(),
                account.getPhone(),
                null,
                null,
                null,
                null,
                null,
                "0",
                null,
                userPrincipal,
                LocalDateTime.now(),
                userPrincipal,
                LocalDateTime.now()
        );
        authenticationService.save(authentication);

        //insert initial vehicle information
        TVehicle vehicle = new TVehicle(
                String.valueOf(idGenerator.nextId()),
                null,
                null,
                null,
                null,
                null,
                account.getPhone(),
                0,
                null,
                userPrincipal,
                LocalDateTime.now(),
                userPrincipal,
                LocalDateTime.now()
        );
        vehicleService.save(vehicle);

        return CommonResponse.SUCCESS;
    }

    @Transactional
    @Override
    public CommonResponse<Object> modifyAccount(TAccount account) {
        String userPrincipal = AuthenticationInterceptor.getUserPrincipal();
        if (!StrUtil.isEmpty(account.getPassword())) {
            account.setPassword(DigestUtils.md5DigestAsHex(account.getPassword().getBytes()));
            account.setUpdatedBy(userPrincipal)
                    .setUpdatedTime(LocalDateTime.now());

            accountMapper.updateById(account);
            return CommonResponse.SUCCESS;
        }
        if (!StrUtil.isEmpty(account.getPhone())) {
            TAccount tAccount = accountMapper.selectOne(
                    Wrappers.<TAccount>lambdaQuery()
                            .eq(TAccount::getPhone, account.getPhone())
            );
            if (tAccount != null) {
                return CommonResponse.failed("该号码已被其他帐号绑定");
            }
            //获取原手机号，用与查询关联信息
            TAccount old = accountMapper.selectOne(
                    Wrappers.<TAccount>lambdaQuery()
                            .eq(TAccount::getId, account.getId())
            );
            String oldPhone = old.getPhone();
            //更新认证表关联信息
            authenticationService.update(
                    Wrappers.<TAuthentication>lambdaUpdate()
                            .eq(TAuthentication::getPhone, oldPhone)
                            .set(TAuthentication::getPhone, account.getPhone())
                            .set(TAuthentication::getUpdatedBy, userPrincipal)
                            .set(TAuthentication::getUpdatedTime, LocalDateTime.now())
            );
            //更新交通工具表关联信息手机号
            vehicleService.update(
                    Wrappers.<TVehicle>lambdaUpdate()
                            .eq(TVehicle::getPhone, oldPhone)
                            .set(TVehicle::getUpdatedBy, userPrincipal)
                            .set(TVehicle::getUpdatedTime, LocalDateTime.now())
                            .set(TVehicle::getPhone, account.getPhone())
            );
            //更新账号表信息
            account.setUpdatedBy(userPrincipal)
                            .setUpdatedTime(LocalDateTime.now());
            accountMapper.updateById(account);
            return CommonResponse.SUCCESS;
        }
        return CommonResponse.failed("请输不能为空");
    }

    @Override
    @Transactional
    public CommonResponse<Object> delAccount(String id) {
        TAccount account = accountMapper.selectById(id);
        if (account == null) {
            return CommonResponse.failed("account not exist");
        }
        String phone = account.getPhone();
        //delete authentication information by phone

        authenticationService.remove(
                Wrappers.<TAuthentication>lambdaQuery()
                        .eq(TAuthentication::getPhone, phone)
        );

        //delete vehicle information by phone

        vehicleService.remove(
                Wrappers.<TVehicle>lambdaQuery()
                        .eq(TVehicle::getPhone, phone)
        );
        int i = accountMapper.deleteById(id);
        if (i > 0) {
            return CommonResponse.SUCCESS;
        }
        return CommonResponse.failed("数据不存在");
    }
}
